package org.pinda.server;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;

import org.pinda.network.IPacket;
import org.pinda.network.PacketUtils;
import org.pinda.network.util.Stream;

public class ServerClient {
	
	private Socket socket;
	private Stream stream;
	
	public ServerClient(Socket socket) {
		this.socket = socket;
	}
	
	/**
	 * Checks if we can read a full packet
	 * @return true if we got enough data buffered
	 * @throws IOException when the TCP Stream fails
	 */
	public boolean canReadPacket() throws IOException {
		if(stream == null) {
			DataInputStream inStream = new DataInputStream(socket.getInputStream());
			if(inStream.available() >= 4) {
				int length = inStream.readInt();
				stream = new Stream(length);
			}
			return canReadPacket();
		} else {
			if(stream.isFull()) {
				return true;
			} else {
				DataInputStream inStream = new DataInputStream(socket.getInputStream());
				if(inStream.available() > 0) {
					int bytesRead = inStream.read(stream.getRawBuffer(), stream.getWriteOffset(), Math.min(inStream.available(), stream.getWriteAvailable()));
					stream.addToWriteOffset(bytesRead);
				}
				return false;
			}
		}
	}
	
	public void sendPacket(IPacket packet) throws IOException {
		DataOutputStream outStream = new DataOutputStream(socket.getOutputStream());
		PacketUtils.writePacket(outStream, packet);
	}
	
	public void close() throws IOException {
		socket.close();
	}
	
	public Stream getStream() {
		return stream;
	}
	
	public String toString() {
		return socket.getRemoteSocketAddress().toString().substring(1);
	}

}
